package com.twu.biblioteca;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Scanner;

public class BibliotecaApp {


    private ArrayList<User> users = new ArrayList<User>();

    //Asset maps are <Item:Availability>
    private LinkedHashMap<String, String> books = new LinkedHashMap<String, String>();
    private LinkedHashMap<Movie, String> movies = new LinkedHashMap<Movie, String>();

    private String currentUser;

    public BibliotecaApp() {
        users.add(new User("001", "pass", "John Smith", "johnsmith@gmail.com", "98765432"));
        users.add(new User("002", "abc123", "Dick Jones", "dj@example.com", "98997677"));
        users.add(new User("003", "password", "Harry Anderson", "handerson@domain.com", "90001111"));
        currentUser = null;

        books.put("Moby Dick", null);
        books.put("Harry Potter", "001");
        books.put("The Lord of the Rings", null);
        books.put("The da Vinci Code", null);
        books.put("Test Driven Development by Example", null);
        books.put("Head First Java", null);
        books.put("Animal Farm", "002");
        books.put("1984", null);
        books.put("The Bible", null);
        books.put("Pride and Prejudice", null);

        movies.put(new Movie("Star Trek", 2009, "JJ Abrams", 7), null);
        movies.put(new Movie("The Dark Knight", 2008, "Christopher Nolan", 8), "003");
        movies.put(new Movie("Inception", 2010, "Christopher Nolan", 9), null);
        movies.put(new Movie("The Hunger Games", 2012, "Gary Ross", 7), null);
        movies.put(new Movie("The Avengers", 2012, "Joss Whedon", 8), null);
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        BibliotecaApp app = new BibliotecaApp();
        System.out.println(app.welcomeMessage());
        while (true) {
            System.out.println("Enter credentials: user password");
            String result = app.logIn(scanner.nextLine());
            System.out.println(result);
            if (result.startsWith("Logged in"))
                break;
        }
        while (true) {
            System.out.println(app.menu());
            System.out.println(app.processOption(scanner.nextLine()));
        }
    }

    public String welcomeMessage() {
        return "Welcome to Biblioteca!\n";
    }

    public String logIn(String credentials) {
        int firstSpace = credentials.indexOf(" ");
        String number = credentials.substring(0, firstSpace);
        String password = credentials.substring(firstSpace+1);
        for (User user : users)
            if (user.getNumber().equals(number) && user.getPassword().equals(password)) {
                currentUser = number;
                return "Logged in as " + number + "\n";
            }
        return "Invalid credentials\n";
    }

    public String getCurrentUser() {
        return currentUser;
    }

    public String menu() {
        String retVal = "";
        retVal = retVal.concat("Menu:\n");
        retVal = retVal.concat("To list all books enter: listB\n");
        retVal = retVal.concat("To list all movies enter: listM\n");
        retVal = retVal.concat("To find who has borrowed a book enter: findB booktitle\n");
        retVal = retVal.concat("To find who has borrowed a movie enter: findM movietitle\n");
        retVal = retVal.concat("To check out a book enter: checkoutB booktitle\n");
        retVal = retVal.concat("To return a book enter: returnB booktitle\n");
        retVal = retVal.concat("To check out a movie enter: checkoutM movietitle\n");
        retVal = retVal.concat("To return a movie enter: returnM movietitle\n");
        retVal = retVal.concat("To review your user details enter: details\n");
        return retVal;
    }

    public String processOption(String choice) {
        if (choice.equals("listB"))
            return bookList();
        if (choice.equals("listM"))
            return movieList();
        if (choice.startsWith("findB "))
            return bookFind(choice.substring(6));
        if (choice.startsWith("findM "))
            return movieFind(choice.substring(6));
        if (choice.startsWith("checkoutB "))
            return checkOutBook(choice.substring(10));
        if (choice.startsWith("returnB "))
            return returnBook(choice.substring(8));
        if (choice.startsWith("checkoutM "))
            return checkOutMovie(choice.substring(10));
        if (choice.startsWith("returnM "))
            return returnMovie(choice.substring(8));
        if (choice.equals("details"))
            return getCurrentUserDetails();

        return "Select a valid option!\n";
    }

    public String bookList() {
        String retVal = "Book list:\n";
        for (Map.Entry<String, String> book : books.entrySet()){
            retVal = retVal.concat(book.getKey()).concat(" : ");
            if (book.getValue() == null)
                retVal = retVal.concat("Available\n");
            else
                retVal = retVal.concat("On loan\n");
        }
        return retVal;
    }

    public String movieList() {
        String retVal = "Movie list:\n";
        for (Map.Entry<Movie, String> movie : movies.entrySet()){
            retVal = retVal.concat(movie.getKey().toString()).concat(" : ");
            if (movie.getValue() == null)
                retVal = retVal.concat("Available\n");
            else
                retVal = retVal.concat("On loan\n");
        }
        return retVal;
    }

    public String bookFind(String title) {
        if (!bookExists(title))
            return "Book does not exist.\n";
        if (books.get(title) != null)
            return "Book borrowed by user " + books.get(title) + ".\n";
        else
            return "Book has not been borrowed.\n";
    }

    public String movieFind(String title) {
        if (!movieExists(title))
            return "Movie does not exist.\n";
        if (movies.get(getMovieByTitle(title)) != null)
            return "Movie borrowed by user " + movies.get(getMovieByTitle(title)) + ".\n";
        else
            return "Movie has not been borrowed.\n";
    }

    public String checkOutBook(String title) {
        if (currentUser == null)
            throw new IllegalStateException("Must be logged in to check out a book");
        if (getBookStatus(title)) {
            books.put(title, currentUser);
            return "Thank you! Enjoy the book\n";
        }
        else
            return "That book is not available.\n";
    }

    public Movie getMovieByTitle(String title) {
        for (Movie movie : movies.keySet()) {
            if (movie.getTitle().equals(title))
                return movie;
        }
        return null;
    }

    public String checkOutMovie(String title) {
        if (currentUser == null)
            throw new IllegalStateException("Must be logged in to check out a movie");
        if (getMovieStatus(title)) {
            movies.put(getMovieByTitle(title), currentUser);
            return "Thank you! Enjoy the movie\n";
        }
        else
            return "That movie is not available.\n";
    }

    public boolean bookExists(String title) {
        return books.containsKey(title);
    }

    public boolean movieExists(String title) {
        for (Movie movie : movies.keySet())
            if (movie.getTitle().equals(title))
                return true;
        return false;
    }

    public boolean getBookStatus(String title) {
        return (books.containsKey(title) && books.get(title) == null);
    }

    public boolean getMovieStatus(String title) {
        for (Movie movie : movies.keySet())
            if (movie.getTitle().equals(title) && movies.get(movie) == null)
                return true;
        return false;
    }

    public String returnBook(String title) {
        if (currentUser == null)
            throw new IllegalStateException("Must be logged in to return a book");
        if (bookExists(title) && !getBookStatus(title)) {
            books.put(title, null);
            return "Thank you for returning the book.\n";
        }
        return "That is not a valid book to return.\n";
    }

    public String returnMovie(String title) {
        if (currentUser == null)
            throw new IllegalStateException("Must be logged in to return a movie");
        if (movieExists(title) && !getMovieStatus(title)) {
            movies.put(getMovieByTitle(title), null);
            return "Thank you for returning the movie.\n";
        }
        return "That is not a valid movie to return.\n";
    }

    public String getCurrentUserDetails() {
        if (currentUser == null)
            throw new IllegalStateException("Must be logged in to get user details");
        for (User user : users)
            if (user.getNumber().equals(currentUser))
                return user.getDetails();
        return null;
    }
}
